
/*
 * Copyright 2002-2023 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *版权所有2002-2023原作者。
 *
 *根据Apache许可证2.0版（“许可证”）许可；
 *除非符合许可证的规定，否则您不得使用此文件。
 *您可以在以下网址获取许可证副本
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *除非适用法律要求或书面同意，否则软件
 *根据许可证分发是在“按原样”的基础上分发的，
 *无任何明示或暗示的保证或条件。
 *有关管理权限的特定语言，请参阅许可证
 *许可证下的限制。
 */

package org.springframework.context.support;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.BeansException;
import org.springframework.beans.CachedIntrospectionResults;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.support.ResourceEditorRegistrar;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ApplicationStartupAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.HierarchicalMessageSource;
import org.springframework.context.LifecycleProcessor;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.expression.StandardBeanExpressionResolver;
import org.springframework.context.weaving.LoadTimeWeaverAware;
import org.springframework.context.weaving.LoadTimeWeaverAwareProcessor;
import org.springframework.core.NativeDetector;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.core.metrics.StartupStep;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;

/**
 * Abstract implementation of the {@link org.springframework.context.ApplicationContext}
 * interface. Doesn't mandate the type of storage used for configuration; simply
 * implements common context functionality. Uses the Template Method design pattern,
 * requiring concrete subclasses to implement abstract methods.
 *
 * <p>In contrast to a plain BeanFactory, an ApplicationContext is supposed
 * to detect special beans defined in its internal bean factory:
 * Therefore, this class automatically registers
 * {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessors},
 * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors},
 * and {@link org.springframework.context.ApplicationListener ApplicationListeners}
 * which are defined as beans in the context.
 *
 * <p>A {@link org.springframework.context.MessageSource} may also be supplied
 * as a bean in the context, with the name "messageSource"; otherwise, message
 * resolution is delegated to the parent context. Furthermore, a multicaster
 * for application events can be supplied as an "applicationEventMulticaster" bean
 * of type {@link org.springframework.context.event.ApplicationEventMulticaster}
 * in the context; otherwise, a default multicaster of type
 * {@link org.springframework.context.event.SimpleApplicationEventMulticaster} will be used.
 *
 * <p>Implements resource loading by extending
 * {@link org.springframework.core.io.DefaultResourceLoader}.
 * Consequently treats non-URL resource paths as class path resources
 * (supporting full class path resource names that include the package path,
 * e.g. "mypackage/myresource.dat"), unless the {@link #getResourceByPath}
 * method is overridden in a subclass.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Mark Fisher
 * @author Stephane Nicoll
 * @author Sam Brannen
 * @author Sebastien Deleuze
 * @author Brian Clozel
 * @since January 21, 2001
 * @see #refreshBeanFactory
 * @see #getBeanFactory
 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
 * @see org.springframework.beans.factory.config.BeanPostProcessor
 * @see org.springframework.context.event.ApplicationEventMulticaster
 * @see org.springframework.context.ApplicationListener
 * @see org.springframework.context.MessageSource
 */
/**
 *｛@link org.springframework.context.ApplicationContext｝的抽象实现
 *接口。不强制要求使用用于配置的存储类型；仅仅
 *实现通用上下文功能。使用模板方法设计模式，
 *需要具体的子类来实现抽象方法。
 *
 *<p>与普通BeanFactory相比，ApplicationContext应该
 *要检测其内部bean工厂中定义的特殊bean：
 *因此，这个类会自动注册
 *｛@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcesses｝，
 *｛@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors｝，
 *和｛@link org.springframework.context.ApplicationListener ApplicationListeners｝
 *其在上下文中被定义为bean。
 *
 *＜p＞还可以提供｛@link org.springframework.context.MessageSource｝
 *作为上下文中的bean，名称为“messageSource”；否则，消息
 *解析被委托给父上下文。此外，多播
 *for应用程序事件可以作为“applicationEventMultimaster”bean提供
 *类型为{@linkorg.springframework.context.event.ApplicationEventMulticast}
 *在上下文中；否则，类型为的默认多播
 *将使用{@linkorg.springframework.context.event.SimpleApplicationEventMulticast}。
 *
 *＜p＞通过扩展实现资源加载
 *｛@link org.springframework.core.io.DefaultResourceLoader｝。
 *因此，将非URL资源路径视为类路径资源
 *（支持包括包路径的完整类路径资源名称，
 *例如“mypackage/myresource.dat”），除非｛@link#getResourceByPath｝
 *方法在子类中被重写。
 *
 *@作者罗德·约翰逊
 *@作者Juergen Hoeller
 *@作者Mark Fisher
 *@作者Stephane Nicoll
 *@作者Sam Brannen
 *@作者Sebastien Deleuze
 *@作者Brian Clozel
 *@自2001年1月21日起
 *@见#refreshBeanFactory
 *@见#getBeanFactory
 *@参见org.springframework.beans.factory.config.BeanFactoryPostProcessor
 *@参见org.springframework.beans.factory.config.BeanPostProcessor
 *@参见org.springframework.context.event.ApplicationEventMultimaster
 *@参见org.springframework.context.ApplicationListener
 *@参见org.springframework.context.MessageSource
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {

	/**
	 * Name of the MessageSource bean in the factory.
	 * If none is supplied, message resolution is delegated to the parent.
	 * @see MessageSource
	 */
	/**
	 *工厂中MessageSource bean的名称。
	 *如果没有提供，则将消息解析委派给父级。
	 *@see消息源
	 */
	public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";

	/**
	 * Name of the LifecycleProcessor bean in the factory.
	 * If none is supplied, a DefaultLifecycleProcessor is used.
	 * @see org.springframework.context.LifecycleProcessor
	 * @see org.springframework.context.support.DefaultLifecycleProcessor
	 */
	/**
	 *工厂中的LifecycleProcessor bean的名称。
	 *如果没有提供，则使用DefaultLifecycleProcessor。
	 *@参见org.springframework.context.LifecycleProcessor
	 *@请参阅org.springframework.context.support.DefaultLifecycleProcessor
	 */
	public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";

	/**
	 * Name of the ApplicationEventMulticaster bean in the factory.
	 * If none is supplied, a default SimpleApplicationEventMulticaster is used.
	 * @see org.springframework.context.event.ApplicationEventMulticaster
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	/**
	 *工厂中ApplicationEventMulticastbean的名称。
	 *如果未提供，则使用默认的SimpleApplicationEventMultimaster。
	 *@参见org.springframework.context.event.ApplicationEventMultimaster
	 *@请参阅org.springframework.context.event.SimpleApplicationEventMultimaster
	 */
	public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";


	static {
		// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
		// 急切地加载ContextClosedEvent类以避免奇怪的类加载器问题
		// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
		// 关于WebLogic 8.1中的应用程序关闭。（达斯汀·伍兹报道）
		ContextClosedEvent.class.getName();
	}


	/** Logger used by this class. Available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());

	/** Unique id for this context, if any. */
	private String id = ObjectUtils.identityToString(this);

	/** Display name. */
	private String displayName = ObjectUtils.identityToString(this);

	/** Parent context. */
	@Nullable
	private ApplicationContext parent;

	/** Environment used by this context. */
	@Nullable
	private ConfigurableEnvironment environment;

	/** BeanFactoryPostProcessors to apply on refresh. */
	private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

	/** System time in milliseconds when this context started. */
	private long startupDate;

	/** Flag that indicates whether this context is currently active. */
	private final AtomicBoolean active = new AtomicBoolean();

	/** Flag that indicates whether this context has been closed already. */
	private final AtomicBoolean closed = new AtomicBoolean();

	/** Synchronization monitor for the "refresh" and "destroy". */
	private final Object startupShutdownMonitor = new Object();

	/** Reference to the JVM shutdown hook, if registered. */
	@Nullable
	private Thread shutdownHook;

	/** ResourcePatternResolver used by this context. */
	private final ResourcePatternResolver resourcePatternResolver;

	/** LifecycleProcessor for managing the lifecycle of beans within this context. */
	@Nullable
	private LifecycleProcessor lifecycleProcessor;

	/** MessageSource we delegate our implementation of this interface to. */
	@Nullable
	private MessageSource messageSource;

	/** Helper class used in event publishing. */
	@Nullable
	private ApplicationEventMulticaster applicationEventMulticaster;

	/** Application startup metrics. **/
	private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;

	/** Statically specified listeners. */
	private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

	/** Local listeners registered before refresh. */
	@Nullable
	private Set<ApplicationListener<?>> earlyApplicationListeners;

	/** ApplicationEvents published before the multicaster setup. */
	@Nullable
	private Set<ApplicationEvent> earlyApplicationEvents;


	/**
	 * Create a new AbstractApplicationContext with no parent.
	 */
	/** Logger used by this class. Available to subclasses. */
	受保护的最终日志记录器=LogFactory.getLog（getClass（））；

	/**此上下文的唯一id（如果有）*/
	private字符串id=ObjectUtils.identityToString（this）；

	/**显示名称*/
	private字符串displayName=ObjectUtils.identityToString（this）；

	/**父上下文*/
	@可为null
	private ApplicationContext父级；

	/**此上下文使用的环境*/
	@可为null
	私有可配置环境；

	/**刷新时要应用的BeanFactoryPostProcessors*/
	private最终列表<BeanFactoryPostProcessor>beanFactoryPostProcesses=new ArrayList<>（）；

	/**此上下文启动时的系统时间（以毫秒为单位）*/
	私人长期启动日期；

	/**指示此上下文当前是否处于活动状态的标志*/
	private最终AtomicBoolean活动=新AtomicBoolean（）；

	/**指示此上下文是否已关闭的标志*/
	private最终AtomicBoolean关闭=新AtomicBoolean（）；

	/**“刷新”和“销毁”的同步监视器*/
	private最终对象startupShutdownMonitor=新对象（）；

	/**对JVM关闭挂钩的引用（如果已注册）*/
	@可为null
	专用线程关闭书；

	/**此上下文使用的ResourcePatternResolver*/
	私有最终资源PatternResolver资源PatternSolutionr；

	/**LifecycleProcessor，用于在此上下文中管理bean的生命周期*/
	@可为null
	专用生命周期处理器生命周期处理器；

	/**我们将此接口的实现委托给MessageSource*/
	@可为null
	private消息源MessageSource；

	/**事件发布中使用的帮助程序类*/
	@可为null
	私有应用程序EventMultimaster应用程序EventMulti-master；

	/**应用程序启动指标**/
	private ApplicationStartup ApplicationStartup=ApplicationStartup.DEFAULT；

	/**静态指定的侦听器*/
	私有最终集<ApplicationListener<？>>applicationListeners=新的LinkedHashSet＜＞（）；

	/**本地侦听器在刷新前已注册*/
	@可为null
	private集<ApplicationListener<？>>早期应用程序监听器；

	/**在多主机安装之前发布的ApplicationEvents*/
	@可为null
	private集＜ApplicationEvent＞早期ApplicationEvents；


	/**
	 *创建一个没有父级的新AbstractApplicationContext。
	 */
	public AbstractApplicationContext() {
		this.resourcePatternResolver = getResourcePatternResolver();
	}

	/**
	 * Create a new AbstractApplicationContext with the given parent context.
	 * @param parent the parent context
	 */
	/**
	 *使用给定的父上下文创建一个新的AbstractApplicationContext。
	 *@param parent父上下文
	 */
	public AbstractApplicationContext(@Nullable ApplicationContext parent) {
		this();
		setParent(parent);
	}


	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------
	// Implementation of ApplicationContext interface
	// ApplicationContext接口的实现
	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------

	/**
	 * Set the unique id of this application context.
	 * <p>Default is the object id of the context instance, or the name
	 * of the context bean if the context is itself defined as a bean.
	 * @param id the unique id of the context
	 */
	/**
	 *设置此应用程序上下文的唯一id。
	 *＜p＞默认值是上下文实例的对象id或名称
	 *如果上下文本身被定义为bean，则上下文bean的值。
	 *@param id上下文的唯一id
	 */
	@Override
	public void setId(String id) {
		this.id = id;
	}

	@Override
	public String getId() {
		return this.id;
	}

	@Override
	public String getApplicationName() {
		return "";
	}

	/**
	 * Set a friendly name for this context.
	 * Typically done during initialization of concrete context implementations.
	 * <p>Default is the object id of the context instance.
	 */
	/**
	 *为此上下文设置一个友好名称。
	 *通常在具体上下文实现的初始化过程中完成。
	 *＜p＞默认值是上下文实例的对象id。
	 */
	public void setDisplayName(String displayName) {
		Assert.hasLength(displayName, "Display name must not be empty");
		this.displayName = displayName;
	}

	/**
	 * Return a friendly name for this context.
	 * @return a display name for this context (never {@code null})
	 */
	/**
	 *返回此上下文的友好名称。
	 *@返回此上下文的显示名称（从不｛@code null｝）
	 */
	@Override
	public String getDisplayName() {
		return this.displayName;
	}

	/**
	 * Return the parent context, or {@code null} if there is no parent
	 * (that is, this context is the root of the context hierarchy).
	 */
	/**
	 *返回父上下文，如果没有父上下文，则返回｛@code null｝
	 *（也就是说，这个上下文是上下文层次结构的根）。
	 */
	@Override
	@Nullable
	public ApplicationContext getParent() {
		return this.parent;
	}

	/**
	 * Set the {@code Environment} for this application context.
	 * <p>Default value is determined by {@link #createEnvironment()}. Replacing the
	 * default with this method is one option but configuration through {@link
	 * #getEnvironment()} should also be considered. In either case, such modifications
	 * should be performed <em>before</em> {@link #refresh()}.
	 * @see org.springframework.context.support.AbstractApplicationContext#createEnvironment
	 */
	/**
	 *为此应用程序上下文设置｛@code Environment｝。
	 *<p>默认值由{@link#createEnvironment（）}确定。更换
	 *此方法的默认值是一个选项，但通过{@link进行配置
	 *还应考虑#getEnvironment（）｝。无论哪种情况，此类修改
	 *应在</em>之前执行<em>{@link#refresh（）}。
	 *请参阅org.springframework.context.support.AbstractApplicationContext#createEnvironment
	 */
	@Override
	public void setEnvironment(ConfigurableEnvironment environment) {
		this.environment = environment;
	}

	/**
	 * Return the {@code Environment} for this application context in configurable
	 * form, allowing for further customization.
	 * <p>If none specified, a default environment will be initialized via
	 * {@link #createEnvironment()}.
	 */
	/**
	 *以可配置的方式返回此应用程序上下文的｛@code Environment｝
	 *形式，允许进一步定制。
	 *＜p＞如果未指定，默认环境将通过
	 *｛@link#createEnvironment（）｝。
	 */
	@Override
	public ConfigurableEnvironment getEnvironment() {
		if (this.environment == null) {
			this.environment = createEnvironment();
		}
		return this.environment;
	}

	/**
	 * Create and return a new {@link StandardEnvironment}.
	 * <p>Subclasses may override this method in order to supply
	 * a custom {@link ConfigurableEnvironment} implementation.
	 */
	/**
	 *创建并返回一个新的｛@link StandardEnvironment｝。
	 *＜p＞子类可以覆盖此方法，以便提供
	 *自定义｛@link可配置环境｝实现。
	 */
	protected ConfigurableEnvironment createEnvironment() {
		return new StandardEnvironment();
	}

	/**
	 * Return this context's internal bean factory as AutowireCapableBeanFactory,
	 * if already available.
	 * @see #getBeanFactory()
	 */
	/**
	 *将此上下文的内部bean工厂返回为AutowireCapableBeanFactory，
	 *如果已经可用。
	 *@参见#getBeanFactory（）
	 */
	@Override
	public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
		return getBeanFactory();
	}

	/**
	 * Return the timestamp (ms) when this context was first loaded.
	 */
	/**
	 *返回首次加载此上下文时的时间戳（ms）。
	 */
	@Override
	public long getStartupDate() {
		return this.startupDate;
	}

	/**
	 * Publish the given event to all listeners.
	 * <p>Note: Listeners get initialized after the MessageSource, to be able
	 * to access it within listener implementations. Thus, MessageSource
	 * implementations cannot publish events.
	 * @param event the event to publish (may be application-specific or a
	 * standard framework event)
	 */
	/**
	 *将给定的事件发布给所有侦听器。
	 *＜p＞注意：监听器在MessageSource之后进行初始化，以便能够
	 *以便在侦听器实现中访问它。因此，MessageSource
	 *实现无法发布事件。
	 *@param event要发布的事件（可能是特定于应用程序的，也可能是
	 *标准框架事件）
	 */
	@Override
	public void publishEvent(ApplicationEvent event) {
		publishEvent(event, null);
	}

	/**
	 * Publish the given event to all listeners.
	 * <p>Note: Listeners get initialized after the MessageSource, to be able
	 * to access it within listener implementations. Thus, MessageSource
	 * implementations cannot publish events.
	 * @param event the event to publish (may be an {@link ApplicationEvent}
	 * or a payload object to be turned into a {@link PayloadApplicationEvent})
	 */
	/**
	 *将给定的事件发布给所有侦听器。
	 *＜p＞注意：监听器在MessageSource之后进行初始化，以便能够
	 *以便在侦听器实现中访问它。因此，MessageSource
	 *实现无法发布事件。
	 *@param event要发布的事件（可能是｛@link ApplicationEvent｝
	 *或要转换为｛@link PayloadApplicationEvent｝的有效负载对象）
	 */
	@Override
	public void publishEvent(Object event) {
		publishEvent(event, null);
	}

	/**
	 * Publish the given event to all listeners.
	 * @param event the event to publish (may be an {@link ApplicationEvent}
	 * or a payload object to be turned into a {@link PayloadApplicationEvent})
	 * @param eventType the resolved event type, if known
	 * @since 4.2
	 */
	/**
	 *将给定的事件发布给所有侦听器。
	 *@param event要发布的事件（可能是｛@link ApplicationEvent｝
	 *或要转换为｛@link PayloadApplicationEvent｝的有效负载对象）
	 *@param eventType解析的事件类型（如果已知）
	 *@自4.2起
	 */
	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
		Assert.notNull(event, "Event must not be null");

		// Decorate event as an ApplicationEvent if necessary
		// 如有必要，将事件装饰为ApplicationEvent
		ApplicationEvent applicationEvent;
		if (event instanceof ApplicationEvent applEvent) {
			applicationEvent = applEvent;
		}
		else {
			applicationEvent = new PayloadApplicationEvent<>(this, event, eventType);
			if (eventType == null) {
				eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
			}
		}

		// Multicast right now if possible - or lazily once the multicaster is initialized
		// 如果可能的话，立即进行多播，或者在初始化多播后延迟
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}

		// Publish event via parent context as well...
		// 也通过父上下文发布事件。。。
		if (this.parent != null) {
			if (this.parent instanceof AbstractApplicationContext abstractApplicationContext) {
				abstractApplicationContext.publishEvent(event, eventType);
			}
			else {
				this.parent.publishEvent(event);
			}
		}
	}

	/**
	 * Return the internal ApplicationEventMulticaster used by the context.
	 * @return the internal ApplicationEventMulticaster (never {@code null})
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
	/**
	 *返回上下文使用的内部ApplicationEventMultimaster。
	 *@返回内部ApplicationEventMultimaster（从不｛@code null｝）
	 *如果上下文尚未初始化，则@throws IllegalStateException
	 */
	ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
		if (this.applicationEventMulticaster == null) {
			throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
					"call 'refresh' before multicasting events via the context: " + this);
		}
		return this.applicationEventMulticaster;
	}

	@Override
	public void setApplicationStartup(ApplicationStartup applicationStartup) {
		Assert.notNull(applicationStartup, "applicationStartup must not be null");
		this.applicationStartup = applicationStartup;
	}

	@Override
	public ApplicationStartup getApplicationStartup() {
		return this.applicationStartup;
	}

	/**
	 * Return the internal LifecycleProcessor used by the context.
	 * @return the internal LifecycleProcessor (never {@code null})
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
	/**
	 *返回上下文使用的内部LifecycleProcessor。
	 *@返回内部LifecycleProcessor（从不｛@code null｝）
	 *如果上下文尚未初始化，则@throws IllegalStateException
	 */
	LifecycleProcessor getLifecycleProcessor() throws IllegalStateException {
		if (this.lifecycleProcessor == null) {
			throw new IllegalStateException("LifecycleProcessor not initialized - " +
					"call 'refresh' before invoking lifecycle methods via the context: " + this);
		}
		return this.lifecycleProcessor;
	}

	/**
	 * Return the ResourcePatternResolver to use for resolving location patterns
	 * into Resource instances. Default is a
	 * {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver},
	 * supporting Ant-style location patterns.
	 * <p>Can be overridden in subclasses, for extended resolution strategies,
	 * for example in a web environment.
	 * <p><b>Do not call this when needing to resolve a location pattern.</b>
	 * Call the context's {@code getResources} method instead, which
	 * will delegate to the ResourcePatternResolver.
	 * @return the ResourcePatternResolver for this context
	 * @see #getResources
	 * @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
	 */
	/**
	 *返回ResourcePatternResolver以用于解析位置模式
	 *到资源实例中。默认为
	 *｛@link org.springframework.core.io.support.PathMatchingResourcePatternResolver｝，
	 *支持Ant风格的位置模式。
	 *＜p＞可以在子类中重写，用于扩展解析策略，
	 *例如在web环境中。
	 *<p><b>在需要解析位置模式时不要调用此函数</b>
	 *改为调用上下文的｛@code getResources｝方法，该方法
	 *将委托给ResourcePatternResolver。
	 *@return此上下文的ResourcePatternResolver
	 *@参见#getResources
	 *@请参阅org.springframework.core.io.support.PathMatchingResourcePatternResolver
	 */
	protected ResourcePatternResolver getResourcePatternResolver() {
		return new PathMatchingResourcePatternResolver(this);
	}


	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------
	// Implementation of ConfigurableApplicationContext interface
	// 可配置ApplicationContext接口的实现
	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------

	/**
	 * Set the parent of this application context.
	 * <p>The parent {@linkplain ApplicationContext#getEnvironment() environment} is
	 * {@linkplain ConfigurableEnvironment#merge(ConfigurableEnvironment) merged} with
	 * this (child) application context environment if the parent is non-{@code null} and
	 * its environment is an instance of {@link ConfigurableEnvironment}.
	 * @see ConfigurableEnvironment#merge(ConfigurableEnvironment)
	 */
	/**
	 *设置此应用程序上下文的父级。
	 *<p>父｛@linkplain ApplicationContext#getEnvironment（）环境｝是
	 *｛@linkplain ConfigurationEnvironment#merge（ConfigurationEnvironment）与合并
	 *这个（子）应用程序上下文环境，如果父级是非-{@code-null}并且
	 *其环境是｛@link ConfigurationEnvironment｝的一个实例。
	 *@请参阅可配置环境#merge（可配置环境）
	 */
	@Override
	public void setParent(@Nullable ApplicationContext parent) {
		this.parent = parent;
		if (parent != null) {
			Environment parentEnvironment = parent.getEnvironment();
			if (parentEnvironment instanceof ConfigurableEnvironment configurableEnvironment) {
				getEnvironment().merge(configurableEnvironment);
			}
		}
	}

	@Override
	public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
		Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
		this.beanFactoryPostProcessors.add(postProcessor);
	}

	/**
	 * Return the list of BeanFactoryPostProcessors that will get applied
	 * to the internal BeanFactory.
	 */
	/**
	 *返回将要应用的BeanFactoryPostProcessors的列表
	 *到内部BeanFactory。
	 */
	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
		return this.beanFactoryPostProcessors;
	}

	@Override
	public void addApplicationListener(ApplicationListener<?> listener) {
		Assert.notNull(listener, "ApplicationListener must not be null");
		if (this.applicationEventMulticaster != null) {
			this.applicationEventMulticaster.addApplicationListener(listener);
		}
		this.applicationListeners.add(listener);
	}

	@Override
	public void removeApplicationListener(ApplicationListener<?> listener) {
		Assert.notNull(listener, "ApplicationListener must not be null");
		if (this.applicationEventMulticaster != null) {
			this.applicationEventMulticaster.removeApplicationListener(listener);
		}
		this.applicationListeners.remove(listener);
	}

	/**
	 * Return the list of statically specified ApplicationListeners.
	 */
	/**
	 *返回静态指定的ApplicationListener的列表。
	 */
	public Collection<ApplicationListener<?>> getApplicationListeners() {
		return this.applicationListeners;
	}

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// Prepare this context for refreshing.
			// 准备此上下文以进行刷新。
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 告诉子类刷新内部bean工厂。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 准备bean工厂以便在此上下文中使用。
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 允许在上下文子类中对bean工厂进行后处理。
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				// 调用在上下文中注册为bean的工厂处理器。
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册拦截bean创建的bean处理器。
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// Initialize message source for this context.
				// 初始化此上下文的消息源。
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化此上下文的事件多播。
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 初始化特定上下文子类中的其他特殊bean。
				onRefresh();

				// Check for listener beans and register them.
				// 检查侦听器bean并注册它们。
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 实例化所有剩余的（非惰性init）singleton。
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 最后一步：发布相应的事件。
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				// 销毁已创建的singleton以避免挂起资源。
				destroyBeans();

				// Reset 'active' flag.
				// 重置“活动”标志。
				cancelRefresh(ex);

				// Propagate exception to caller.
				// 向调用方传播异常。
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// 重置Spring核心中的常见自省缓存，因为我们
				// might not ever need metadata for singleton beans anymore...
				// 可能再也不需要单例bean的元数据了。。。
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

	/**
	 * Prepare this context for refreshing, setting its startup date and
	 * active flag as well as performing any initialization of property sources.
	 */
	/**
	 *准备此上下文以进行刷新，设置其启动日期和
	 *活动标志以及执行属性源的任何初始化。
	 */
	protected void prepareRefresh() {
		// Switch to active.
		// 切换到活动状态。
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		// 初始化上下文环境中的任何占位符属性源。
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// 验证所有标记为必需的属性是否可解析：
		// see ConfigurablePropertyResolver#setRequiredProperties
		// 请参阅ConfigurationPropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		// 存储预刷新ApplicationListeners。。。
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			// 将本地应用程序侦听器重置为预刷新状态。
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// 允许收集早期ApplicationEvents，
		// to be published once the multicaster is available...
		// 待多播主机可用后发布。。。
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

	/**
	 * <p>Replace any stub property sources with actual instances.
	 * @see org.springframework.core.env.PropertySource.StubPropertySource
	 * @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources
	 */
	/**
	 *<p>用实际实例替换任何存根属性源。
	 *@参见org.springframework.core.env.PropertySource.StubPropertySource
	 *@see org.springframework.web.context.support.WebApplicationContextUtils#initServlet属性源
	 */
	protected void initPropertySources() {
		// For subclasses: do nothing by default.
		// 对于子类：默认情况下不执行任何操作。
	}

	/**
	 * Tell the subclass to refresh the internal bean factory.
	 * @return the fresh BeanFactory instance
	 * @see #refreshBeanFactory()
	 * @see #getBeanFactory()
	 */
	/**
	 *告诉子类刷新内部bean工厂。
	 *@返回新鲜的BeanFactory实例
	 *@参见#refreshBeanFactory（）
	 *@参见#getBeanFactory（）
	 */
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}

	/**
	 * Configure the factory's standard context characteristics,
	 * such as the context's ClassLoader and post-processors.
	 * @param beanFactory the BeanFactory to configure
	 */
	/**
	 *配置工厂的标准上下文特征，
	 *例如上下文的ClassLoader和后处理器。
	 *@param beanFactory要配置的beanFactory
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		// 告诉内部bean工厂使用上下文的类加载器等。
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 使用上下文回调配置bean工厂。
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// BeanFactory接口未在普通工厂中注册为可解析类型。
		// MessageSource registered (and found for autowiring) as a bean.
		// MessageSource已注册（并为自动布线找到）为bean。
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 注册早期后处理器，以便将内部bean检测为ApplicationListeners。
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		// 检测LoadTimeWeaver并准备编织（如果发现）。
		if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			// 为类型匹配设置临时ClassLoader。
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		// 注册默认环境bean。
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
		if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
			beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
		}
	}

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. The initial definition resources will have been loaded but no
	 * post-processors will have run and no derived bean definitions will have been
	 * registered, and most importantly, no beans will have been instantiated yet.
	 * <p>This template method allows for registering special BeanPostProcessors
	 * etc in certain AbstractApplicationContext subclasses.
	 * @param beanFactory the bean factory used by the application context
	 */
	/**
	 *在应用程序上下文的标准之后修改其内部bean工厂
	 *初始化。将加载初始定义资源，但没有
	 *后处理器将已经运行，并且没有派生的bean定义
	 *已注册，最重要的是，还没有任何bean被实例化。
	 *<p>此模板方法允许注册特殊的BeanPostProcessors
	 *在某些AbstractApplicationContext子类中。
	 *@param beanFactory应用程序上下文使用的bean工厂
	 */
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	}

	/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 */
	/**
	 *实例化并调用所有注册的BeanFactoryPostProcessor bean，
	 *尊重明确的秩序。
	 *＜p＞必须在单例实例化之前调用。
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// 检测LoadTimeWeaver并准备编织（如果在此期间发现）
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		// （例如，通过ConfigurationClassPostProcessor注册的@Bean方法）
		if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

	/**
	 * Instantiate and register all BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before any instantiation of application beans.
	 */
	/**
	 *实例化并注册所有BeanPostProcessor bean，
	 *尊重明确的秩序。
	 *＜p＞必须在应用程序bean的任何实例化之前调用。
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

	/**
	 * Initialize the MessageSource.
	 * Use parent's if none defined in this context.
	 */
	/**
	 *初始化MessageSource。
	 *如果在此上下文中未定义，请使用父级。
	 */
	protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			// 使MessageSource知道父MessageSource。
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource hms &&
					hms.getParentMessageSource() == null) {
				// Only set parent context as parent MessageSource if no parent MessageSource
				// 如果没有父MessageSource，则仅将父上下文设置为父MessageSource
				// registered already.
				// 已注册。
				hms.setParentMessageSource(getInternalParentMessageSource());
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			// 使用空的MessageSource可以接受getMessage调用。
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
			}
		}
	}

	/**
	 * Initialize the ApplicationEventMulticaster.
	 * Uses SimpleApplicationEventMulticaster if none defined in the context.
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	/**
	 *初始化ApplicationEventMultimaster。
	 *如果上下文中未定义，则使用SimpleApplicationEventMultimaster。
	 *@请参阅org.springframework.context.event.SimpleApplicationEventMultimaster
	 */
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}

	/**
	 * Initialize the LifecycleProcessor.
	 * Uses DefaultLifecycleProcessor if none defined in the context.
	 * @see org.springframework.context.support.DefaultLifecycleProcessor
	 */
	/**
	 *初始化生命周期处理器。
	 *如果上下文中未定义，则使用DefaultLifecycleProcessor。
	 *@请参阅org.springframework.context.support.DefaultLifecycleProcessor
	 */
	protected void initLifecycleProcessor() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		else {
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			defaultProcessor.setBeanFactory(beanFactory);
			this.lifecycleProcessor = defaultProcessor;
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
			}
		}
	}

	/**
	 * Template method which can be overridden to add context-specific refresh work.
	 * Called on initialization of special beans, before instantiation of singletons.
	 * <p>This implementation is empty.
	 * @throws BeansException in case of errors
	 * @see #refresh()
	 */
	/**
	 *可以重写的模板方法，以添加特定于上下文的刷新工作。
	 *在初始化特殊bean时调用，在实例化singleton之前调用。
	 *<p>此实现为空。
	 *出现错误时@throws BeansException
	 *@见#refresh（）
	 */
	protected void onRefresh() throws BeansException {
		// For subclasses: do nothing by default.
		// 对于子类：默认情况下不执行任何操作。
	}

	/**
	 * Add beans that implement ApplicationListener as listeners.
	 * Doesn't affect other listeners, which can be added without being beans.
	 */
	/**
	 *添加实现ApplicationListener的bean作为侦听器。
	 *不会影响其他侦听器，这些侦听器可以在不作为bean的情况下添加。
	 */
	protected void registerListeners() {
		// Register statically specified listeners first.
		// 首先注册静态指定的侦听器。
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// 不要在这里初始化FactoryBeans：我们需要保留所有常规bean
		// uninitialized to let post-processors apply to them!
		// 未初始化以允许后处理器应用于它们！
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		// 发布早期的应用程序事件，现在我们终于有了多主机。。。
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

	/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	/**
	 *完成该上下文的bean工厂的初始化，
	 *初始化所有剩余的单例bean。
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 初始化此上下文的转换服务。
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no BeanFactoryPostProcessor
		// 如果没有BeanFactoryPostProcessor，则注册默认嵌入值解析程序
		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
		// （例如PropertySourcesPlaceholderConfigurer bean）在以下时间之前注册了任何：
		// at this point, primarily for resolution in annotation attribute values.
		// 此时，主要用于注释属性值的解析。
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		// 尽早初始化LoadTimeWeaverWare bean，以便尽早注册它们的转换器。
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		// 停止使用临时ClassLoader进行类型匹配。
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		// 允许缓存所有bean定义元数据，而不期望有进一步的更改。
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 实例化所有剩余的（非惰性init）singleton。
		beanFactory.preInstantiateSingletons();
	}

	/**
	 * Finish the refresh of this context, invoking the LifecycleProcessor's
	 * onRefresh() method and publishing the
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 */
	/**
	 *通过调用LifecycleProcessor的
	 *onRefresh（）方法并发布
	 *｛@link org.springframework.context.event.ContextRefreshedEvent｝。
	 */
	@SuppressWarnings("deprecation")
	protected void finishRefresh() {
		// Clear context-level resource caches (such as ASM metadata from scanning).
		// 清除上下文级别的资源缓存（如扫描中的ASM元数据）。
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		// 初始化此上下文的生命周期处理器。
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		// 首先将刷新传播到生命周期处理器。
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		// 发布最终事件。
		publishEvent(new ContextRefreshedEvent(this));
	}

	/**
	 * Cancel this context's refresh attempt, resetting the {@code active} flag
	 * after an exception got thrown.
	 * @param ex the exception that led to the cancellation
	 */
	/**
	 *取消此上下文的刷新尝试，重置｛@code active｝标志
	 *在抛出异常之后。
	 *@param ex导致取消的异常
	 */
	protected void cancelRefresh(BeansException ex) {
		this.active.set(false);
	}

	/**
	 * Reset Spring's common reflection metadata caches, in particular the
	 * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}
	 * and {@link CachedIntrospectionResults} caches.
	 * @since 4.2
	 * @see ReflectionUtils#clearCache()
	 * @see AnnotationUtils#clearCache()
	 * @see ResolvableType#clearCache()
	 * @see CachedIntrospectionResults#clearClassLoader(ClassLoader)
	 */
	/**
	 *重置Spring的常见反射元数据缓存，特别是
	 *｛@link ReflectionUtils｝、｛@linkAnnotationUntils｝、{@linkResolutileType｝
	 *和{@linkCachedIntrosectionResults}缓存。
	 *@自4.2起
	 *@请参阅ReflectionUtils#clearCache（）
	 *@请参阅AnnotationUntils#clearCache（）
	 *@请参阅可解析类型#clearCache（）
	 *@see CachedIntrosectionResults#clearClassLoader（ClassLoader）
	 */
	protected void resetCommonCaches() {
		ReflectionUtils.clearCache();
		AnnotationUtils.clearCache();
		ResolvableType.clearCache();
		CachedIntrospectionResults.clearClassLoader(getClassLoader());
	}


	/**
	 * Register a shutdown hook {@linkplain Thread#getName() named}
	 * {@code SpringContextShutdownHook} with the JVM runtime, closing this
	 * context on JVM shutdown unless it has already been closed at that time.
	 * <p>Delegates to {@code doClose()} for the actual closing procedure.
	 * @see Runtime#addShutdownHook
	 * @see ConfigurableApplicationContext#SHUTDOWN_HOOK_THREAD_NAME
	 * @see #close()
	 * @see #doClose()
	 */
	/**
	 *注册一个名为｛@linkplain Thread#getName（）的关闭挂钩
	 *｛@code SpringContextShutdownHook｝与JVM运行时一起关闭
	 *JVM关闭时的上下文，除非当时它已经关闭。
	 *<p>委托{@code doClose（）}执行实际的关闭过程。
	 *@参见运行时#addShutdownHook
	 *@请参阅可配置的应用程序上下文#SHUTDOWN_HOOK_THREAD_NAME
	 *@见#close（）
	 *@见#doClose（）
	 */
	@Override
	public void registerShutdownHook() {
		if (this.shutdownHook == null) {
			// No shutdown hook registered yet.
			// 尚未注册关机挂钩。
			this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
				@Override
				public void run() {
					synchronized (startupShutdownMonitor) {
						doClose();
					}
				}
			};
			Runtime.getRuntime().addShutdownHook(this.shutdownHook);
		}
	}

	/**
	 * Close this application context, destroying all beans in its bean factory.
	 * <p>Delegates to {@code doClose()} for the actual closing procedure.
	 * Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
	 * @see #doClose()
	 * @see #registerShutdownHook()
	 */
	/**
	 *关闭此应用程序上下文，销毁其bean工厂中的所有bean。
	 *<p>委托{@code doClose（）}执行实际的关闭过程。
	 *如果已经注册，还会删除JVM关闭挂钩，因为不再需要它了。
	 *@见#doClose（）
	 *@参见#registerShutdownHook（）
	 */
	@Override
	public void close() {
		synchronized (this.startupShutdownMonitor) {
			doClose();
			// If we registered a JVM shutdown hook, we don't need it anymore now:
			// 如果我们注册了JVM关闭挂钩，那么现在就不需要它了：
			// We've already explicitly closed the context.
			// 我们已经明确关闭了上下文。
			if (this.shutdownHook != null) {
				try {
					Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
				}
				catch (IllegalStateException ex) {
					// ignore - VM is already shutting down
					// 忽略-虚拟机已经关闭
				}
			}
		}
	}

	/**
	 * Actually performs context closing: publishes a ContextClosedEvent and
	 * destroys the singletons in the bean factory of this application context.
	 * <p>Called by both {@code close()} and a JVM shutdown hook, if any.
	 * @see org.springframework.context.event.ContextClosedEvent
	 * @see #destroyBeans()
	 * @see #close()
	 * @see #registerShutdownHook()
	 */
	/**
	 *实际执行上下文关闭：发布ContextClosedEvent并
	 *销毁此应用程序上下文的bean工厂中的singleton。
	 *<p>由{@code close（）}和JVM关闭挂钩（如果有的话）调用。
	 *@参见org.springframework.context.event.ContextClosedEvent
	 *@见#destroyBeans（）
	 *@见#close（）
	 *@参见#registerShutdownHook（）
	 */
	@SuppressWarnings("deprecation")
	protected void doClose() {
		// Check whether an actual close attempt is necessary...
		// 检查是否需要实际的关闭尝试。。。
		if (this.active.get() && this.closed.compareAndSet(false, true)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Closing " + this);
			}

			try {
				// Publish shutdown event.
				// 发布关闭事件。
				publishEvent(new ContextClosedEvent(this));
			}
			catch (Throwable ex) {
				logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
			}

			// Stop all Lifecycle beans, to avoid delays during individual destruction.
			// 停止所有生命周期bean，以避免在单个销毁过程中出现延迟。
			if (this.lifecycleProcessor != null) {
				try {
					this.lifecycleProcessor.onClose();
				}
				catch (Throwable ex) {
					logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
				}
			}

			// Destroy all cached singletons in the context's BeanFactory.
			// 销毁上下文的BeanFactory中所有缓存的singleton。
			destroyBeans();

			// Close the state of this context itself.
			// 关闭此上下文本身的状态。
			closeBeanFactory();

			// Let subclasses do some final clean-up if they wish...
			// 如果子类愿意的话，让它们做一些最后的清理。。。
			onClose();

			// Reset local application listeners to pre-refresh state.
			// 将本地应用程序侦听器重置为预刷新状态。
			if (this.earlyApplicationListeners != null) {
				this.applicationListeners.clear();
				this.applicationListeners.addAll(this.earlyApplicationListeners);
			}

			// Switch to inactive.
			// 切换到非活动状态。
			this.active.set(false);
		}
	}

	/**
	 * Template method for destroying all beans that this context manages.
	 * The default implementation destroy all cached singletons in this context,
	 * invoking {@code DisposableBean.destroy()} and/or the specified
	 * "destroy-method".
	 * <p>Can be overridden to add context-specific bean destruction steps
	 * right before or right after standard singleton destruction,
	 * while the context's BeanFactory is still active.
	 * @see #getBeanFactory()
	 * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
	 */
	/**
	 *用于销毁此上下文管理的所有bean的模板方法。
	 *默认实现销毁在此上下文中所有缓存的singleton，
	 *调用｛@code DisposableBean.dedestroy（）｝和/或指定的
	 *“销毁方法”。
	 *＜p＞可以重写以添加上下文特定的bean销毁步骤
	 *就在标准单体破坏之前或之后，
	 *而上下文的BeanFactory仍然处于活动状态。
	 *@参见#getBeanFactory（）
	 *请参阅org.springframework.beans.factory.config.ConfiguratableBeanFactory#destroySingletons（）
	 */
	protected void destroyBeans() {
		getBeanFactory().destroySingletons();
	}

	/**
	 * Template method which can be overridden to add context-specific shutdown work.
	 * The default implementation is empty.
	 * <p>Called at the end of {@link #doClose}'s shutdown procedure, after
	 * this context's BeanFactory has been closed. If custom shutdown logic
	 * needs to execute while the BeanFactory is still active, override
	 * the {@link #destroyBeans()} method instead.
	 */
	/**
	 *可以重写的模板方法，以添加上下文特定的关闭工作。
	 *默认实现为空。
	 *＜p＞在｛@link#doClose｝的关闭过程结束时调用，之后
	 *此上下文的BeanFactory已关闭。如果自定义关闭逻辑
	 *需要在BeanFactory仍处于活动状态时执行，覆盖
	 *改为{@link#destroyBeans（）}方法。
	 */
	protected void onClose() {
		// For subclasses: do nothing by default.
		// 对于子类：默认情况下不执行任何操作。
	}

	@Override
	public boolean isActive() {
		return this.active.get();
	}

	/**
	 * Assert that this context's BeanFactory is currently active,
	 * throwing an {@link IllegalStateException} if it isn't.
	 * <p>Invoked by all {@link BeanFactory} delegation methods that depend
	 * on an active context, i.e. in particular all bean accessor methods.
	 * <p>The default implementation checks the {@link #isActive() 'active'} status
	 * of this context overall. May be overridden for more specific checks, or for a
	 * no-op if {@link #getBeanFactory()} itself throws an exception in such a case.
	 */
	/**
	 *断言此上下文的BeanFactory当前处于活动状态，
	 *如果不是，则抛出｛@link IllegalStateException｝。
	 *<p>由依赖的所有｛@link BeanFactory｝委派方法调用
	 *在活动上下文上，即特别是所有bean访问器方法。
	 *＜p＞默认实现检查｛@link#isActive（）‘active’｝状态
	 *整体而言。对于更具体的检查或
	 *在这种情况下，如果{@link#getBeanFactory（）}本身抛出异常，则没有操作。
	 */
	protected void assertBeanFactoryActive() {
		if (!this.active.get()) {
			if (this.closed.get()) {
				throw new IllegalStateException(getDisplayName() + " has been closed already");
			}
			else {
				throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
			}
		}
	}


	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------
	// Implementation of BeanFactory interface
	// BeanFactory接口的实现
	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------

	@Override
	public Object getBean(String name) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name);
	}

	@Override
	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name, requiredType);
	}

	@Override
	public Object getBean(String name, Object... args) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name, args);
	}

	@Override
	public <T> T getBean(Class<T> requiredType) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(requiredType);
	}

	@Override
	public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(requiredType, args);
	}

	@Override
	public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType);
	}

	@Override
	public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType);
	}

	@Override
	public boolean containsBean(String name) {
		return getBeanFactory().containsBean(name);
	}

	@Override
	public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().isSingleton(name);
	}

	@Override
	public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().isPrototype(name);
	}

	@Override
	public boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().isTypeMatch(name, typeToMatch);
	}

	@Override
	public boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().isTypeMatch(name, typeToMatch);
	}

	@Override
	@Nullable
	public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().getType(name);
	}

	@Override
	@Nullable
	public Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().getType(name, allowFactoryBeanInit);
	}

	@Override
	public String[] getAliases(String name) {
		return getBeanFactory().getAliases(name);
	}


	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------
	// Implementation of ListableBeanFactory interface
	// ListableBeanFactory接口的实现
	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------

	@Override
	public boolean containsBeanDefinition(String beanName) {
		return getBeanFactory().containsBeanDefinition(beanName);
	}

	@Override
	public int getBeanDefinitionCount() {
		return getBeanFactory().getBeanDefinitionCount();
	}

	@Override
	public String[] getBeanDefinitionNames() {
		return getBeanFactory().getBeanDefinitionNames();
	}

	@Override
	public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType, allowEagerInit);
	}

	@Override
	public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType, allowEagerInit);
	}

	@Override
	public String[] getBeanNamesForType(ResolvableType type) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForType(type);
	}

	@Override
	public String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
	}

	@Override
	public String[] getBeanNamesForType(@Nullable Class<?> type) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForType(type);
	}

	@Override
	public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
	}

	@Override
	public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBeansOfType(type);
	}

	@Override
	public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
			throws BeansException {

		assertBeanFactoryActive();
		return getBeanFactory().getBeansOfType(type, includeNonSingletons, allowEagerInit);
	}

	@Override
	public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForAnnotation(annotationType);
	}

	@Override
	public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
			throws BeansException {

		assertBeanFactoryActive();
		return getBeanFactory().getBeansWithAnnotation(annotationType);
	}

	@Override
	@Nullable
	public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
			throws NoSuchBeanDefinitionException {

		assertBeanFactoryActive();
		return getBeanFactory().findAnnotationOnBean(beanName, annotationType);
	}

	@Override
	@Nullable
	public <A extends Annotation> A findAnnotationOnBean(
			String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
			throws NoSuchBeanDefinitionException {

		assertBeanFactoryActive();
		return getBeanFactory().findAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit);
	}

	@Override
	public <A extends Annotation> Set<A> findAllAnnotationsOnBean(
			String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
			throws NoSuchBeanDefinitionException {

		assertBeanFactoryActive();
		return getBeanFactory().findAllAnnotationsOnBean(beanName, annotationType, allowFactoryBeanInit);
	}


	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------
	// Implementation of HierarchicalBeanFactory interface
	// 层次结构BeanFactory接口的实现
	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------

	@Override
	@Nullable
	public BeanFactory getParentBeanFactory() {
		return getParent();
	}

	@Override
	public boolean containsLocalBean(String name) {
		return getBeanFactory().containsLocalBean(name);
	}

	/**
	 * Return the internal bean factory of the parent context if it implements
	 * ConfigurableApplicationContext; else, return the parent context itself.
	 * @see org.springframework.context.ConfigurableApplicationContext#getBeanFactory
	 */
	/**
	 *如果实现了，则返回父上下文的内部bean工厂
	 *可配置的ApplicationContext；否则，返回父上下文本身。
	 *请参阅org.springframework.context.ConfiguratableApplicationContext#getBeanFactory
	 */
	@Nullable
	protected BeanFactory getInternalParentBeanFactory() {
		return (getParent() instanceof ConfigurableApplicationContext cac ?
				cac.getBeanFactory() : getParent());
	}


	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------
	// Implementation of MessageSource interface
	// MessageSource接口的实现
	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------

	@Override
	public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
		return getMessageSource().getMessage(code, args, defaultMessage, locale);
	}

	@Override
	public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException {
		return getMessageSource().getMessage(code, args, locale);
	}

	@Override
	public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
		return getMessageSource().getMessage(resolvable, locale);
	}

	/**
	 * Return the internal MessageSource used by the context.
	 * @return the internal MessageSource (never {@code null})
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
	/**
	 *返回上下文使用的内部MessageSource。
	 *@return内部MessageSource（从不｛@code null｝）
	 *如果上下文尚未初始化，则@throws IllegalStateException
	 */
	private MessageSource getMessageSource() throws IllegalStateException {
		if (this.messageSource == null) {
			throw new IllegalStateException("MessageSource not initialized - " +
					"call 'refresh' before accessing messages via the context: " + this);
		}
		return this.messageSource;
	}

	/**
	 * Return the internal message source of the parent context if it is an
	 * AbstractApplicationContext too; else, return the parent context itself.
	 */
	/**
	 *如果父上下文是
	 *AbstractApplicationContext也是；否则，返回父上下文本身。
	 */
	@Nullable
	protected MessageSource getInternalParentMessageSource() {
		return (getParent() instanceof AbstractApplicationContext abstractApplicationContext ?
				abstractApplicationContext.messageSource : getParent());
	}


	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------
	// Implementation of ResourcePatternResolver interface
	// ResourcePatternResolver接口的实现
	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------

	@Override
	public Resource[] getResources(String locationPattern) throws IOException {
		return this.resourcePatternResolver.getResources(locationPattern);
	}


	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------
	// Implementation of Lifecycle interface
	// 生命周期接口的实施
	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------

	@Override
	public void start() {
		getLifecycleProcessor().start();
		publishEvent(new ContextStartedEvent(this));
	}

	@Override
	public void stop() {
		getLifecycleProcessor().stop();
		publishEvent(new ContextStoppedEvent(this));
	}

	@Override
	public boolean isRunning() {
		return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning());
	}


	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------
	// Abstract methods that must be implemented by subclasses
	// 必须由子类实现的抽象方法
	//---------------------------------------------------------------------
	// ---------------------------------------------------------------------

	/**
	 * Subclasses must implement this method to perform the actual configuration load.
	 * The method is invoked by {@link #refresh()} before any other initialization work.
	 * <p>A subclass will either create a new bean factory and hold a reference to it,
	 * or return a single BeanFactory instance that it holds. In the latter case, it will
	 * usually throw an IllegalStateException if refreshing the context more than once.
	 * @throws BeansException if initialization of the bean factory failed
	 * @throws IllegalStateException if already initialized and multiple refresh
	 * attempts are not supported
	 */
	/**
	 *子类必须实现此方法才能执行实际的配置加载。
	 *该方法在进行任何其他初始化工作之前由{@link#refresh（）}调用。
	 *＜p＞一个子类将创建一个新的bean工厂并保存对它的引用，
	 *或者返回它所持有的单个BeanFactory实例。在后一种情况下
	 *如果多次刷新上下文，通常会引发IllegalStateException。
	 *如果bean工厂初始化失败，@throws BeansException
	 *@throws IllegalStateException（如果已初始化并多次刷新）
	 *不支持尝试
	 */
	protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

	/**
	 * Subclasses must implement this method to release their internal bean factory.
	 * This method gets invoked by {@link #close()} after all other shutdown work.
	 * <p>Should never throw an exception but rather log shutdown failures.
	 */
	/**
	 *子类必须实现此方法才能释放其内部bean工厂。
	 *在完成所有其他关闭工作后，｛@link#close（）｝会调用此方法。
	 *<p>永远不应该抛出异常，而应该记录关闭失败。
	 */
	protected abstract void closeBeanFactory();

	/**
	 * Subclasses must return their internal bean factory here. They should implement the
	 * lookup efficiently, so that it can be called repeatedly without a performance penalty.
	 * <p>Note: Subclasses should check whether the context is still active before
	 * returning the internal bean factory. The internal factory should generally be
	 * considered unavailable once the context has been closed.
	 * @return this application context's internal bean factory (never {@code null})
	 * @throws IllegalStateException if the context does not hold an internal bean factory yet
	 * (usually if {@link #refresh()} has never been called) or if the context has been
	 * closed already
	 * @see #refreshBeanFactory()
	 * @see #closeBeanFactory()
	 */
	/**
	 *子类必须在此处返回其内部bean工厂。他们应该实施
	 *高效地查找，以便可以重复调用它而不会对性能造成影响。
	 *＜p＞注意：子类应该检查上下文在
	 *返回内部豆工厂。内部工厂通常应
	 *一旦上下文已经关闭，就被认为是不可用的。
	 *@返回此应用程序上下文的内部bean工厂（从不｛@code null｝）
	 *如果上下文尚未包含内部bean工厂，则@throws IllegalStateException
	 *（通常如果从未调用过{@link#refresh（）}）或上下文
	 *已关闭
	 *@参见#refreshBeanFactory（）
	 *@参见#closeBeanFactory（）
	 */
	@Override
	public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;


	/**
	 * Return information about this context.
	 */
	/**
	 *返回有关此上下文的信息。
	 */
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder(getDisplayName());
		sb.append(", started on ").append(new Date(getStartupDate()));
		ApplicationContext parent = getParent();
		if (parent != null) {
			sb.append(", parent: ").append(parent.getDisplayName());
		}
		return sb.toString();
	}

}
